const Cell = require('./Cell');
const Grid = require('./Grid');
const assert = require('./assert');

// this takes too long, needs better pruning
{
  const grid = new Grid(9);
  grid.addAnimal(4, 4, 'o', 0);
  grid.addAnimal(4, 3, 'o', 1);
  grid.addAnimal(5, 7, 'o', 2);
  grid.addAnimal(5, 6, 'o', 3);
  grid.addAnimal(5, 4, 's', 0);
  grid.addAnimal(5, 3, 's', 1);
  grid.addAnimal(6, 6, 's', 2);
  grid.addAnimal(6, 4, 'f', 0);
  grid.addAnimal(4, 6, 'f', 1);
  grid.addAnimal(6, 5, 'b', 0);
  grid.addAnimal(3, 4, 'b', 1);
  grid.addAnimal(3, 5, 'b', 2);
  grid.addAnimal(4, 5, 'b', 3);
  grid.addWall(5, 5);
  grid.addPathBoth(2, 7);
  grid.addPathBoth(2, 8);
  grid.addPathBoth(3, 7);
  grid.addPathBoth(3, 8);
  grid.addPathBoth(7, 2);
  grid.addPathBoth(7, 5);
  // grid.print();
  // grid.solve();
}

{
  const grid = new Grid(4, true);
  grid.addAnimal(1, 3, 'f', 0);
  grid.addAnimal(2, 1, 'f', 1);
  grid.addWall(1, 1);
  grid.addWall(1, 2);
  grid.addWall(3, 1);
  grid.addWall(4, 2);
  assert(grid.hasEmptyCell(), 'should detect unreachable cell');
}

{
  const grid = new Grid(4);
  grid.addAnimal(1, 3, 'f', 0);
  grid.addAnimal(2, 1, 'f', 1);
  grid.addWall(1, 1);
  grid.addWall(1, 2);
  assert(grid.solve(), 'can solve');
}

{
  const grid = new Grid(6);
  grid.addAnimal(1, 3, 'f', 0);
  grid.addAnimal(6, 5, 'f', 1);
  grid.addAnimal(1, 6, 'o', 1);
  grid.addAnimal(5, 5, 'o', 0);
  grid.addWall(5, 2);
  grid.addPathBoth(2, 2);
  grid.addPathBoth(3, 2);
  grid.addPathBoth(4, 3);
  grid.addPathBoth(4, 4);
  grid.addPathBoth(5, 4);
  assert(grid.solve(), 'can solve');
}

{
  const grid = new Grid(6);
  grid.addAnimal(6, 4, 's', 0);
  grid.addAnimal(1, 5, 's', 1);
  grid.addAnimal(5, 3, 'h', 0);
  grid.addAnimal(6, 6, 'h', 1);
  grid.addAnimal(1, 6, 'r', 0);
  grid.addAnimal(6, 1, 'r', 1);
  grid.addPathBoth(2, 4);
  grid.addPathBoth(3, 2);
  grid.addPathBoth(4, 2);
  assert(grid.solve(), 'can solve');
}

{
  const grid = new Grid(7);
  grid.addAnimal(1, 1, 'w', 0);
  grid.addAnimal(7, 4, 'w', 1);
  grid.addAnimal(7, 7, 'w', 2);
  grid.addAnimal(3, 2, 'h', 0);
  grid.addAnimal(7, 1, 'h', 1);
  grid.addAnimal(2, 4, 'b', 0);
  grid.addAnimal(6, 5, 'b', 1);
  grid.addAnimal(5, 6, 'b', 2);
  grid.addPathBoth(6, 2);
  grid.addPathBoth(6, 3);
  grid.addPathBoth(3, 5);
  grid.addPathBoth(4, 5);
  assert(grid.solve(), 'can solve');
}

{
  const grid = new Grid(6);
  grid.addAnimal(1, 1, 'f', 0);
  grid.addAnimal(3, 2, 'f', 1);
  grid.addAnimal(1, 2, 'g', 0);
  grid.addAnimal(6, 6, 'g', 1);
  grid.addAnimal(6, 1, 'x', 0);
  grid.addAnimal(1, 3, 'x', 1);
  grid.addAnimal(3, 6, 'r', 0);
  grid.addAnimal(5, 2, 'r', 1);
  grid.addPathBoth(2, 4);
  grid.addPathBoth(2, 5);
  grid.addPathBoth(3, 4);
  grid.addPathBoth(4, 3);
  grid.addPathBoth(5, 5);
  assert(grid.solve(), 'can solve');
}

{
  const grid = new Grid(7);
  grid.addAnimal(1, 3, 'f', 0);
  grid.addAnimal(7, 3, 'f', 1);
  grid.addAnimal(1, 4, 'o', 0);
  grid.addAnimal(7, 1, 'o', 1);
  grid.addPathBoth(4, 2);
  grid.addPathBoth(6, 4);
  grid.addWall(5, 3);
  grid.addWall(2, 6);
  assert(grid.solve(), 'can solve');
}

{
  const grid = new Grid(5, true);
  grid.addAnimal(3, 1, 'f', 0);
  grid.addAnimal(1, 5, 'f', 1);
  grid.addAnimal(1, 1, 'w', 0);
  grid.addAnimal(5, 1, 'w', 1);
  grid.addPathBoth(2, 2);
  grid.addPathBoth(2, 3);
  grid.addPathBoth(2, 4);
  grid.addPathBoth(4, 3);
  grid.addPathBoth(4, 4);
  grid.addWall(5, 2);
  grid.addWall(5, 5);
  grid.print();
  assert(grid.solve(), 'can solve');
}
